/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-11-12     73554       the first version
 */
#include <rtthread.h>

#define DBG_TAG "usermodbus"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

//modbus 头文件
#include "mb.h"
#include "mb_m.h"
#include "mbconfig.h"
#include "user_mb_app.h"

#define slave_id 2

extern void G_ModbusMasterThreadInit(void);

extern USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS]; //主机读取的从机寄存器皆存在此数组

//下面两个结构体是为了更方便处理数据
//mqueue_type sensor_send_data; //用户使用的寄存器结构体
//MSmodbus_type  *Master_rec = &usMRegHoldBuf[slave_id-1][0]; //新建一个结构体指针并指向从机寄存器数据，方便数据处理


/*********************************************************************************/
/* @brief   读Modbus从机寄存器，刷新本机寄存器数组，对数据进行合理性处理
 * @param   null
 * @retval  状态： 0成功，  其它失败
 */
int Custom_modbus_query(void)
{
    eMBMasterReqErrCode error_code = eMBMasterReqReadHoldingRegister(slave_id, 0,  0x02, rt_tick_from_millisecond(5000));
//    eMBMasterReqErrCode error_code = eMBMasterReqReadHoldingRegister(slave_id, 0,  1, rt_tick_from_millisecond(5000));

    if (error_code != MB_MRE_NO_ERR)  //有错误
    {
        LOG_E("modbus error_code:%d", error_code);  //打印错误码
        return-1;
    }
    else
    {
        return 0;
    }
}
/*********************************************************************************/

/*********************************************************************************/
/* @brief   线程入口函数
 * @param
 */
void UserModbus_thread_entry(void)
{
    static int s_RxSuccCnt_i32 = 0;   //读取成功
    static int s_RxErrCnt_i32 = 0;    //读取失败

    while(1)
    {
        rt_uint32_t e;

        Custom_modbus_query();//根据实际使用需求处理
        rt_thread_mdelay(1000);//实际使用时去掉
//        if (rt_event_recv(&sleep_event, ( Wakeup_EVENT_SENSOR_FLAG ), RT_EVENT_FLAG_OR, RT_WAITING_FOREVER, &e) == RT_EOK)
//        {
//           //  LOG_D(" recv event 0x%x\n", e);
//            if(Custom_modbus_query() < 0) //读取
//            {
//                if(++s_RxErrCnt_i32 > 4) //累计5次读取失败，发送传感器读取完成事件
//                {
//                    s_RxErrCnt_i32 = 0;
//                    s_RxSuccCnt_i32 = 0;
//                    LOG_E("Modbus recv err!");
//                    sensor_send_data.Wind_direction  = 0;  //未读取到正确数据
//                    sensor_send_data.Wind_speed      = 0;
//                    sensor_send_data.Temperature     = 0;
//                    sensor_send_data.Humidity        = 0;
//                    sensor_send_data.DPT             = 0;
//                    sensor_send_data.Pressure        = 0;
//                    rt_event_send(&sleep_event, EVENT_Sensor_Done_FLAG4);
//                    rt_event_recv(&sleep_event, ( Wakeup_EVENT_SENSOR_FLAG ), RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER, &e);
//                }
//            }
//            else
//            {
//                if(++s_RxSuccCnt_i32 > 2) //连续3次读取成功，发送传感器读取完成事件
//                {
//                    s_RxSuccCnt_i32 = 0;
//                    s_RxErrCnt_i32 = 0;
//                    LOG_I("Modbus recv succ.");
//                    rt_event_send(&sleep_event, EVENT_Sensor_Done_FLAG4);
//                    rt_event_recv(&sleep_event, ( Wakeup_EVENT_SENSOR_FLAG ), RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER, &e);
//                }
//            }
//
//           rt_thread_mdelay(500);
//        }
    }
}
/*********************************************************************************/

/*********************************************************************************/
int G_UserModbusInit(void)
{
    rt_err_t ret;

    G_ModbusMasterThreadInit();   //启动 modbus master 主机 读 传感器
    G_ModbusSlaveThreadInit();
    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("UserModbus_serial", (void*)UserModbus_thread_entry, RT_NULL, 1024, 25, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }

    return ret;
}
INIT_APP_EXPORT(G_UserModbusInit);   //在main函数前初始化此线程
/*********************************************************************************/
